/**
 * 
 * @authors li junguang (you@example.org)
 * @date    2018-01-23 23:31:11
 * @version $Id$
 */

// 初始化入口
function init(initOptions){
	var options = {
		data: initOptions.data,
		startTime: initOptions.startTime,
		endTime: initOptions.endTime,
		section: initOptions.section || 4,
		trackNum: initOptions.trackNum || 13,
		direction: 0,
		speed: initOptions.speed || 2,
		canvas: '',
		boundsX: 0,
		boundsY: 0,
		leftPadding: 0,
		fontSize: initOptions.fontSize || 14,
		topPadding: initOptions.fontSize || 30,
		fontPadding: initOptions.fontPadding || 5,
		labelWidth: 0,
		color: initOptions.color || '#888',
		drage: {
			time: '',
			drageStatus: false
		}
	};

	var canvas = document.getElementById('canvas');
	options.canvas = canvas;
	if (canvas.getContext){

		var ctx = canvas.getContext('2d');
		ctx.lineWith = 2;
		ctx.textBaseline = 'middle';
		ctx.font = options.fontSize;
		ctx.strokeStyle = options.color;

		options.leftPadding = maxLeftPadding(ctx, options);
		// 边界赋值
		var rect = canvas.getBoundingClientRect();
		options.boundsX = rect.width - options.leftPadding - options.labelWidth;
		options.boundsY = rect.height - options.topPadding;

		nowTime = options.startTime;

		// 初始话对象
		var timeAxis = new TimeAxis({x: options.labelWidth+options.leftPadding+options.fontPadding*2, y: options.topPadding}, {x: options.boundsX, y: options.topPadding}, options.section, options.startTime, options.endTime);
		var trainAxis = new TrainAxis({x: 0, y: options.topPadding}, {x: 0, y: options.boundsY}, options.trackNum);
		var dateFlag = new DateFlag(timeAxis);
		var trains = new Trains(options.data, timeAxis, trainAxis);
		// 绘制计划
		drawSchedule(timeAxis, trainAxis, dateFlag, trains, nowTime, ctx, options);

		// 绑定鼠标按下事件
		canvas.onmousedown = function(e){
			if (dateFlag.canDrage(e.offsetX, e.offsetY)){
				dateFlag.drageStatus = true;
			}

			e.preventDefault();
		}
		// 绑定鼠标移动事件
		canvas.onmousemove = function(e){
			if (dateFlag.drageStatus){
				var speed = options.speed;
				var x = e.offsetX,
					temp = x < timeAxis.startX ? timeAxis.startX : x,
					temp = x > timeAxis.endX ? timeAxis.endX : temp;
				// 计算坐标差
				var diff = temp - dateFlag.X;
				var minutes = (dateFlag.X - timeAxis.startX)/timeAxis.dis + diff/timeAxis.dis
				// 移动方向
				if (diff > 0){
					options.direction = 1;
				} else if (diff < 0){
					options.direction = -1;
				}
				// 移动速度 
				if (x > timeAxis.endX && dateFlag.X >= timeAxis.endX && Date.parse(timeAxis.nowEndTime) < Date.parse(options.endTime)){
					minutes += speed;
				} else if (x < timeAxis.startX && dateFlag.X <= timeAxis.startX && Date.parse(timeAxis.nowStartTime) > Date.parse(options.startTime)) {
					minutes -= speed;
				}
				update(timeAxis, trainAxis, dateFlag, trains, new Date(timeAxis.nowStartTime.copyDate().setMinutes(timeAxis.nowStartTime.getMinutes() + minutes)), ctx, options);

				console.log('drageTime: ' + new Date(timeAxis.nowStartTime.copyDate().setMinutes(minutes)));
			}

			e.preventDefault();
		}
		// 绑定鼠标弹起事件
		canvas.onmouseup = function(e){
			dateFlag.drageStatus = false;
			e.preventDefault();
		}
		// 鼠标移出事件
		canvas.onmouseout = function(e){
			console.log('mouseup' + e);
			// drageStatus = false;
			e.preventDefault();
		}

	} else {
		console.log('You browser can not support Canvas!!!!!!');
	}

}

// 时间标记
var DateFlag = function(timeAxis, fillColor, strokeColor) {
	// 时间轴对象
	this.timeAxis = timeAxis;
	// 时间标记宽度
	this.width = 20;
	// 时间标记高度
	this.height = 10;
	// 当前坐标 - X
	this.X = 0;
	// 当前坐标 - Y
	this.Y = 0;
	// 当前时间
	this.time = '';
	// 拖拽状态
	this.drageStatus = false;
	// 填充颜色
	this.fillColor = fillColor || 'red';
	// 线条颜色
	this.strokeColor = strokeColor || 'red';

	// 绘画
	this.draw = function(ctx, options, date){

		var dis = this.timeAxis.dateToCoordinate(date)
		var point = this.X;
		if (dis >= 0){
			point = dis + this.timeAxis.startX;
			this.X = dis + this.timeAxis.startX;
			this.Y = options.boundsY;
		}

		ctx.beginPath();
		ctx.fillStyle = this.fillColor;
		// 绘制三角形
		ctx.moveTo(point - this.width/2, options.boundsY + this.height);
		ctx.lineTo(point + this.width/2, options.boundsY + this.height);
		ctx.lineTo(point, options.boundsY);			
		ctx.closePath();
		ctx.fill();
		ctx.stroke();


		// 绘制标识线
		ctx.beginPath(); 
		ctx.lineTo(point, options.topPadding);
		ctx.lineTo(point, options.boundsY);
		ctx.strokeStyle = this.strokeColor;
		ctx.stroke();

		ctx.strokeStyle = options.color;
	};

	// 能否拖动
	this.canDrage = function(x, y){
		if (x >= this.X - this.width/2 && x <= this.X + this.width/2
			&& y >= this.Y && y <= this.Y + this.height){
			return true;
		}

		return false;
	}
}

// 坐标轴
var Axis = function(startX, startY, endX, endY, section) {
	this.startX = startX;
	this.startY = startY;
	this.endX = endX;
	this.endY = endY;
	this.section = section;
}

// 时间坐标轴
var TimeAxis = function(sPoint, ePoint, section, sTime, eTime) {
	Axis.call(this, sPoint.x, sPoint.y, ePoint.x, ePoint.y, section);
	this.dis = (this.endX - this.startX) / this.section / 60;
	this.sTime = sTime;
	this.eTime = eTime;
	this.nowStartTime = sTime;
	this.nowEndTime = new Date(sTime.copyDate().setHours(sTime.getHours() + this.section));
	// 时间转坐标
	this.dateToCoordinate = function(date){
		let startStamp = Date.parse(this.nowStartTime);
		let endStamp = Date.parse(this.nowEndTime);
		let dateStamp = Date.parse(date);
		if (dateStamp >= startStamp && dateStamp <= endStamp){
			return (dateStamp - startStamp) / 1000 / 60 * this.dis
		}

		return -1;
	};

	this.draw = function(ctx, options, date, dateFlag){
		if (dateFlag.X <= this.startX){
			// 左边界状态
			if (options.direction > 0){
				// 向右移动
				this.nowStartTime = date.copyDate();
				this.nowEndTime = date.copyDate();
				this.nowEndTime.setHours(date.getHours() + this.section);

			} else if (options.direction < 0){
				// 向左移动
				if (Date.parse(date) === Date.parse(this.startTime)){
					// 计算公式：
					// 在左边界范围内：
					// 当前轴开始时间 = 开始时间
					// 当前轴结束时间 = 开始时间 + 区间个数
					this.nowStartTime = this.sTime.copyDate();
					this.nowEndTime = this.sTime.copyDate();
					this.nowEndTime.setHours(this.sTime.getHours() + this.section);
				} else {
					// 计算公式：
					// 在中间范围内：
					// 当前轴开始时间 = 结束时间 - 区间个数
					// 当前轴结束时间 = 结束时间
					this.nowStartTime = date.copyDate();
					this.nowEndTime = date.copyDate();
					this.nowEndTime.setHours(date.getHours() + this.section);
				}

			}
		} else if (dateFlag.X >= this.endX){
			// 右边界状态
			if (options.direction > 0){
				// 向右移动
				if (Date.parse(date) === Date.parse(this.endTime)){
					// 计算公式：
					// 在右边界范围内：
					// 当前轴开始时间 = 当前指向时间(date) - 区间个数 
					// 当前轴结束时间 = 当前指向时间
					this.nowStartTime = this.eTime.copyDate();
					this.nowStartTime.setHours(this.eTime.getHours() - this.section);
					this.nowEndTime = this.eTime.copyDate();
				} else {
					// 计算公式：
					// 在中间范围内：
					// 当前轴开始时间 = 结束时间 - 区间个数
					// 当前轴结束时间 = 结束时间
					this.nowStartTime = date.copyDate();
					this.nowStartTime.setHours(date.getHours() - this.section);
					this.nowEndTime = date.copyDate();
				}
			} else if (options.direction < 0){
				// 向左移动
				this.nowStartTime = date.copyDate();
				this.nowStartTime.setHours(date.getHours() - this.section);
				this.nowEndTime = date.copyDate();
			}
		}

		// if (options.direction > 0){
		// 	if (date.copyDate().setHours(date.getHours() - this.section) < Date.parse(this.sTime)){
		// 		// 计算公式：
		// 		// 在左边界范围内：
		// 		// 当前轴开始时间 = 开始时间
		// 		// 当前轴结束时间 = 开始时间 + 区间个数
		// 		this.nowStartTime = this.sTime.copyDate();
		// 		this.nowEndTime = this.sTime.copyDate();
		// 		this.nowEndTime.setHours(this.sTime.getHours() + this.section);
		// 	} else if (Date.parse(date) === Date.parse(this.endTime)){
		// 		// 计算公式：
		// 		// 在右边界范围内：
		// 		// 当前轴开始时间 = 当前指向时间(date) - 区间个数 
		// 		// 当前轴结束时间 = 当前指向时间
		// 		this.nowStartTime = this.eTime.copyDate();
		// 		this.nowStartTime.setHours(this.eTime.getHours() - this.section);
		// 		this.nowEndTime = this.eTime.copyDate();
		// 	} else {
		// 		// 计算公式：
		// 		// 在中间范围内：
		// 		// 当前轴开始时间 = 结束时间 - 区间个数
		// 		// 当前轴结束时间 = 结束时间
		// 		this.nowStartTime = date.copyDate();
		// 		this.nowStartTime.setHours(date.getHours() - this.section);
		// 		this.nowEndTime = date.copyDate();
		// 	} 
		// } else if (options.direction < 0){
		// 	if (Date.parse(date) === Date.parse(this.startTime)){
		// 		// 计算公式：
		// 		// 在左边界范围内：
		// 		// 当前轴开始时间 = 开始时间
		// 		// 当前轴结束时间 = 开始时间 + 区间个数
		// 		this.nowStartTime = this.sTime.copyDate();
		// 		this.nowEndTime = this.sTime.copyDate();
		// 		this.nowEndTime.setHours(this.sTime.getHours() + this.section);
		// 	} else {
		// 		// 计算公式：
		// 		// 在中间范围内：
		// 		// 当前轴开始时间 = 结束时间 - 区间个数
		// 		// 当前轴结束时间 = 结束时间
		// 		this.nowStartTime = date.copyDate();
		// 		this.nowStartTime.setHours(date.getHours() - this.section);
		// 		this.nowEndTime = date.copyDate();
		// 	}
		// }

		// if (date.copyDate().setHours(date.getHours() - this.section) < Date.parse(this.sTime)){
		// 	// 计算公式：
		// 	// 在左边界范围内：
		// 	// 当前轴开始时间 = 开始时间
		// 	// 当前轴结束时间 = 开始时间 + 区间个数
		// 	this.nowStartTime = this.sTime.copyDate();
		// 	this.nowEndTime = this.sTime.copyDate();
		// 	this.nowEndTime.setHours(this.sTime.getHours() + this.section);
		// } 
		// // else if (Date.parse(date) < this.eTime.copyDate().setHours(this.eTime.getHours() - this.section)){
		// // 	// 计算公式：
		// // 	// 在中间范围内：
		// // 	// 当前轴开始时间 = 当前指向时间(date) - 区间个数 
		// // 	// 当前轴结束时间 = 当前指向时间
		// // 	this.nowStartTime = this.eTime.copyDate();
		// // 	this.nowStartTime.setHours(this.eTime.getHours() - this.section);
		// // 	this.nowEndTime = this.eTime.copyDate();
		// // } 
		// else if (date.copyDate().setHours(date.getHours() - this.section) >= Date.parse(this.sTime) && Date.parse(date) <= this.eTime.copyDate().setHours(this.eTime.getHours() - this.section)){
		// 	// 计算公式：
		// 	// 在右边界范围内：
		// 	// 当前轴开始时间 = 结束时间 - 区间个数
		// 	// 当前轴结束时间 = 结束时间
		// 	this.nowStartTime = date.copyDate();
		// 	this.nowStartTime.setHours(date.getHours() - this.section);
		// 	this.nowEndTime = date.copyDate();
		// }

		// // 当前坐标轴起始时间
		// // 计算公式：
		// // 在边界范围内：当前轴起点时间 = 起始时间
		// // 超出边界范围：当前轴起点时间 = 当前指向时间(date) - 区间个数
		// this.nowStartTime = date.copyDate().setHours(date.getHours() - this.section) > Date.parse(this.sTime) 
		// 					&& date.copyDate()  ? date.copyDate() : this.sTime.copyDate();
		// date.getHours() - this.section > this.sTime.getHours() && this.nowStartTime.setHours(date.getHours() - this.section);
		// // 当前坐标轴结束时间
		// // 计算公式：
		// // 在边界范围内：当前轴结束时间 = 结束时间
		// // 超出边界范围：当前轴结束时间 = 当起轴起点时间 + 显示区间个数
		// this.nowEndTime = this.nowStartTime.getHours() + this.section <= this.eTime.getHours() ? this.eTime.copyDate() : this.nowStartTime.copyDate();
		// this.nowStartTime.getHours() + this.section <= this.eTime.getHours() && this.nowEndTime.setHours(this.nowStartTime.getHours() + this.section);
		

		// 时间轴
		ctx.beginPath();
		for (let i = 0; i <= this.section; i++){
			let computedTime = this.nowStartTime.copyDate();
			computedTime.setHours(computedTime.getHours() + i);
			// 绘制时间轴标识线
			let timeX = this.dateToCoordinate(computedTime.toHours());
			if (timeX >= 0){
				let width = ctx.measureText(computedTime.getHours()+':00').width;
				ctx.strokeText(computedTime.getHours()+':00', this.startX + timeX - width/2, options.topPadding/2);
				ctx.moveTo(this.startX + timeX, options.topPadding);
				ctx.lineTo(this.startX + timeX, options.boundsY);
			}
		}
		ctx.stroke();
	}
}

// 轨道坐标轴
var TrainAxis = function(sPoint, ePoint, section) {
	Axis.call(this, sPoint.x, sPoint.y, ePoint.x, ePoint.y, section);
	this.dis = (this.endY - this.startY) / section;
	this.name = '道';
	this.label = '计划';

	// 绘制轨道图像
	this.draw = function(ctx, options) {
		// 绘制轨道
		ctx.beginPath();
		// 区间高度
		let perSize = (options.boundsY-options.topPadding)/this.section;

		for (let i = 0; i <= this.section - 1; i++) {
			// 轨道label
			// 计算公式：x = 0, y = 区间高度 * 当前区间标识 + 上边界留白 + 区间高度 / 2
			ctx.strokeText(i+1+this.name, 0, perSize*i + options.topPadding + perSize/2);
			
			// 轨道接车区域-水平线
			// 计算公式：x = 左边界留白, y = 区间高度 * 当前区间标识 + 上边界留白
			ctx.moveTo(options.leftPadding, perSize*i + options.topPadding);
			// 计算公式：x = 显示边界长度, y = 区间高度 * 当前区间标识 + 上边界留白
			ctx.lineTo(options.boundsX, perSize*i + options.topPadding);
			
			// 绘制计划label
			ctx.strokeText(this.label, options.leftPadding+options.fontPadding, perSize*i + options.topPadding + perSize/2);
			
			// 绘制边线
			// 计算公式：x = 左边界留白, y = 区间高度 * 当前区间标识 + 上边界留白
			// ctx.moveTo(options.leftPadding, perSize*i + options.topPadding + perSize);
			// ctx.lineTo(optionts.boundsX, perSize*i + options.topPadding + perSize);
		}
		// 绘制底部边线
		ctx.moveTo(options.leftPadding, options.boundsY);
		ctx.lineTo(options.boundsX, options.boundsY);

		// 绘制计划边线
		ctx.moveTo(options.labelWidth+options.leftPadding+options.fontPadding*2, options.topPadding);
		ctx.lineTo(options.labelWidth+options.leftPadding+options.fontPadding*2, options.boundsY);

		ctx.stroke();
	}

}

var Trains = function(data, timeAxis, trainAxis){
	// 车辆数据
	this.trains = data;
	// 时间轴对象
	this.timeAxis = timeAxis;
	// 轨道轴对象
	this.trainAxis = trainAxis;

	// 绘制火车信息-88
	this.drawTrainInfo = function(ctx, options){
		for (let i = 0; i <= this.trains.length - 1; i++){
			let arriveDate = new Date(this.trains[i].arriveDate);
			let outSetDate = new Date(this.trains[i].outSetDate);
			if (!(Date.parse(outSetDate) <= Date.parse(this.timeAxis.nowStartTime) || Date.parse(arriveDate) >= Date.parse(this.timeAxis.nowEndTime))){
				// drawTrain(trains[i].arriveName, arriveDate, outSetDate, trains[i].trackNum, trains[i].isPlan);
				if (this.trains[i].arriveName === 'D3784'){
					// debugger;
				}
				let start_x = Date.parse(arriveDate) < Date.parse(this.timeAxis.nowStartTime) ? this.timeAxis.startX : this.timeAxis.startX + this.timeAxis.dateToCoordinate(arriveDate);
				let start_y = this.timeAxis.startY + this.trainAxis.dis * this.trains[i].trackNum - this.trainAxis.dis / 2 + (Date.parse(outSetDate) - Date.parse(arriveDate))/1000/60/60;
				let end_x = Date.parse(outSetDate) > Date.parse(this.timeAxis.nowEndTime) ? this.timeAxis.endX : this.timeAxis.startX + this.timeAxis.dateToCoordinate(outSetDate);
				let end_y = start_y;

				// 绘制车辆信息
				ctx.beginPath();
				// 车辆名称
				ctx.strokeText(this.trains[i].arriveName, start_x+(end_x-start_x)/2-ctx.measureText(this.trains[i].arriveName).width/2, start_y-options.fontSize/2);
				
				// 绘制起始点区间
				ctx.beginPath();
				ctx.strokeStyle = '#2900ff';
				ctx.moveTo(start_x, start_y);
				ctx.lineTo(end_x, end_y);
				ctx.lineWith = 2;
				ctx.stroke();


				// 绘制起始点标记
				ctx.beginPath();
				ctx.fillStyle = '#ff5050'
				if (Date.parse(arriveDate) >= Date.parse(this.timeAxis.nowStartTime)){
					// 到达时间
					ctx.strokeText(arriveDate.getMinutes(), start_x - ctx.measureText(arriveDate.getMinutes()).width/2, start_y+options.fontSize/2);
					ctx.arc(start_x, start_y, 2, 0, 2*Math.PI, true);
				}
				if (Date.parse(outSetDate) <= Date.parse(this.timeAxis.nowEndTime)){
					// 结束时间
					ctx.strokeText(outSetDate.getMinutes(), start_x + (end_x-start_x) - ctx.measureText(outSetDate.getMinutes()).width/2, start_y+options.fontSize/2);
					ctx.arc(end_x, start_y, 2, 0, 2*Math.PI, true);
				}
				ctx.fill();

				ctx.strokeStyle = '#888';
			}
		}
	}

	this.isWorkAtTheSameStage = function(){

	}
}

// 绘制计划表
function drawSchedule(timeAxis, trainAxis, dateFlag, trains, date, ctx, options){
	
	dateFlag.draw(ctx, options, date);
	timeAxis.draw(ctx, options, date, dateFlag);
	trainAxis.draw(ctx, options);
	trains.drawTrainInfo(ctx, options);

	ctx.beginPath();
	// 绘制表格边框线
	ctx.moveTo(options.leftPadding, options.topPadding);
	ctx.lineTo(options.leftPadding, options.boundsY);

	ctx.moveTo(options.boundsX, options.topPadding);
	ctx.lineTo(options.boundsX, options.boundsY);

	ctx.stroke();
}

// 更新渲染计划表
function update(timeAxis, trainAxis, dateFlag, trains, date, ctx, options){
	ctx.clearRect(0, 0, options.canvas.width, options.canvas.height);
	drawSchedule(timeAxis, trainAxis, dateFlag, trains, date, ctx, options);
}


// 获得最大左边界补白
function maxLeftPadding(ctx, options){
	var maxWidth = 0;
	// 获得标题最大宽度
	for (var i = 0; i <= options.trackNum - 1; i++){
		var width = ctx.measureText(i + '轨道').width;
		maxWidth = maxWidth < width ? width : maxWidth;
	}
	options.labelWidth = ctx.measureText('计划').width;

	return maxWidth + 5;
}

// 深度拷贝时间 - 拓展Date原型
Date.prototype.copyDate = function(){
	return new Date(this.toString())
}
// 小时取整
Date.prototype.toHours = function(){
	this.setMinutes(0);
	this.setSeconds(0);
	this.setMilliseconds(0);

	return this;
}
// 时间是否为同一天 - 拓展Date原型
Date.prototype.equalDay = function(date){
	return this.getFullYear() === date.getFullYear() && this.getMonth() === date.getMonth() && this.getDay() === date.getDay();
}